package com.lyw.idempotentstarter.bean.impl;

import com.lyw.idempotentstarter.bean.IdempotentStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Arrays;

/**
 * redis执行cas操作
 */
public class RedisIdempotentStorageService implements IdempotentStorageService {

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    private static final String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    private static final String PREFIX = "idempotent:token:";
    private static final String colon = ":";

    @Override
    public boolean storage(String tenantKey, Long employeeId, String path, String token) {
        stringRedisTemplate.opsForValue().set(PREFIX+path+colon+tenantKey+colon+employeeId,token);
        return true;
    }

    @Override
    public boolean del(String tenantKey, Long employeeId, String path, String token) {
        Long execute = stringRedisTemplate.execute(new DefaultRedisScript<Long>(script), Arrays.asList(PREFIX+path+colon+tenantKey+colon+employeeId), token);
        return execute != null && execute != 0L;
    }

    @Override
    public boolean storage(String tenantKey, String path, String token) {
        stringRedisTemplate.opsForValue().set(PREFIX+path+colon+tenantKey,token);
        return true;
    }

    @Override
    public boolean del(String tenantKey, String path, String token) {
        Long execute = stringRedisTemplate.execute(new DefaultRedisScript<Long>(script), Arrays.asList(PREFIX+path+colon+tenantKey), token);
        return execute != null && execute != 0L;
    }
}
